import 'package:flutter/material.dart';

import 'tree_node.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TreeNode root = NamedNode(name: "根节点");

  @override
  void initState() {
    super.initState();
    initNode();
  }

  void initNode() {
    var treeNode = NamedNode(name: "一级节点");
    treeNode.addChild(NamedNode(name: "二级节点"));

    root.addChild(treeNode);
    root.addChild(NamedNode(name: "一级节点"));

    treeNode = NamedNode(name: "一级节点");
    treeNode.addChild(NamedNode(name: "二级节点"));
    treeNode.addChild(NamedNode(name: "二级节点"));
    treeNode.addChild(NamedNode(name: "二级节点"));
    treeNode.addChild(NamedNode(name: "二级节点"));

    root.addChild(treeNode);
    root.addChild(NamedNode(name: "一级节点"));
    root.addChild(NamedNode(name: "一级节点"));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: ListView(
        children: <Widget>[
          _buildTree(root),
        ],
      ),
    );
  }

  bool checkValue(TreeNode node) {
    switch (node.checkState) {
      case SelectedState.selected:
        return true;
      case SelectedState.no:
        return false;
      default:
        return null;
    }
  }

  Widget _buildTree(TreeNode node) {
    List<Widget> children = [];

    if (node.children.isNotEmpty) {
      for (var value in node.children) {
        children.add(_buildTree(value));
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[checkBox(node), if (show(node)) ...children],
      mainAxisSize: MainAxisSize.min,
    );
  }

  Widget checkBox(TreeNode node) {
    Widget w = Row(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: node.level * 10.0),
        ),
        Checkbox(
          value: checkValue(node),
          onChanged: (bool value) {
            if (value == true) {
              node.checkState = SelectedState.selected;
            } else {
              node.checkState = SelectedState.no;
            }
            setState(() {});
          },
          tristate: true,
        ),
        Text(nodeString(node)),
      ],
    );

    return InkWell(
      child: w,
      onTap: () {
        changeShow(node);
      },
    );
  }

  bool show(TreeNode node) {
    return visibleMap[node] != false;
  }

  changeShow(TreeNode node) {
    if (show(node)) {
      visibleMap[node] = false;
    } else {
      visibleMap[node] = true;
    }
    setState(() {});
  }

  Map<TreeNode, bool> visibleMap = {};

  String nodeString(TreeNode node) {
    if (node is NamedNode) {
      return "${node.level.toString()}.${node.name ?? ""}";
    }
    return node.level.toString();
  }
}
